package com.fengze.business.service.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fengze.business.domain.*;
import com.fengze.business.enums.BusinessTypeEnums;
import com.fengze.business.mapper.*;
import com.fengze.common.annotation.AutoSetInsertValue;
import com.fengze.common.annotation.AutoSetUpdateValue;
import com.fengze.common.config.RuoYiConfig;
import com.fengze.common.core.domain.entity.SysUser;
import com.fengze.common.utils.DateUtils;
import com.fengze.common.utils.StringUtils;
import com.fengze.common.utils.file.FileUploadUtils;
import com.fengze.system.mapper.SysUserMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.compressors.FileNameUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fengze.business.service.IContractInfoService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

/**
 * 合同信息Service业务层处理
 *
 * @author lug
 * @date 2024-02-04
 */
@Service
public class ContractInfoServiceImpl implements IContractInfoService
{
    @Autowired
    private ContractInfoMapper contractInfoMapper;

    @Autowired
    private FileInfoMapper fileInfoMapper;

    @Autowired
    private PerformancePlanMapper performancePlanMapper;

    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private PaymentMapper paymentMapper;
    @Autowired
    private ReceivePaymentMapper receivePaymentMapper;

    /**
     * 查询合同信息
     *
     * @param id 合同信息主键
     * @return 合同信息
     */
    @Override
    public ContractInfo selectContractInfoById(Long id)
    {
        ContractInfo contractInfo = contractInfoMapper.selectContractInfoById(id);
        List<FileInfo> fileList = fileInfoMapper.selectListByBusiIdAndType(id,BusinessTypeEnums.CONTRACT.getCode());
        contractInfo.setFileList(fileList);
        List<PerformancePlan> planList = performancePlanMapper.selectListByContractId(id);
        contractInfo.setPlanList(planList);
        return contractInfo;
    }

    /**
     * 查询合同信息列表
     *
     * @param contractInfo 合同信息
     * @return 合同信息
     */
    @Override
    public List<ContractInfo> selectContractInfoList(ContractInfo contractInfo)
    {
        List<ContractInfo> contractInfos = contractInfoMapper.selectContractInfoList(contractInfo);
        for (int i = 0; i < contractInfos.size(); i++) {
            ContractInfo info = contractInfos.get(i);
            Long userId = info.getUserId();
            SysUser sysUser = userMapper.selectUserById(userId);
            info.setCreateUserName(sysUser.getNickName());
            // 查询付款金额
            Payment payment = new Payment();
            payment.setContractId(info.getId());
            payment.setPaymentStatus(2);
            List<Payment> payments = paymentMapper.selectPaymentList(payment);
            BigDecimal paymentTotal = payments.stream().filter(o -> ObjectUtils.isNotEmpty(o.getPaymentMoney()))
                    .map(Payment::getPaymentMoney)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            info.setPaymentTotal(paymentTotal);
            // 查询收款金额
            ReceivePayment receivePayment = new ReceivePayment();
            receivePayment.setContractId(info.getId());
            List<ReceivePayment> receivePayments = receivePaymentMapper.selectReceivePaymentList(receivePayment);
            BigDecimal receiveTotal = receivePayments.stream().filter(o -> ObjectUtils.isNotEmpty(o.getReceiveMoney()))
                    .map(ReceivePayment::getReceiveMoney)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            info.setReceiveTotal(receiveTotal);
        }
        return contractInfos;
    }

    /**
     * 新增合同信息
     *
     * @param contractInfo 合同信息
     * @return 结果
     */
    @Override
    public int insertContractInfo(ContractInfo contractInfo)
    {
        contractInfo.setCreateTime(DateUtils.getNowDate());
        return contractInfoMapper.insertContractInfo(contractInfo);
    }

    /**
     * 修改合同信息
     *
     * @param contractInfo 合同信息
     * @return 结果
     */
    @Override
    public int updateContractInfo(ContractInfo contractInfo)
    {
        contractInfo.setUpdateTime(DateUtils.getNowDate());
        return contractInfoMapper.updateContractInfo(contractInfo);
    }

    /**
     * 批量删除合同信息
     *
     * @param ids 需要删除的合同信息主键
     * @return 结果
     */

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteContractInfoByIds(Long[] ids)
    {
        // 删除附件信息
        fileInfoMapper.deleteByBusiIdsAndType(ids,BusinessTypeEnums.CONTRACT.getCode());
        // 删除合同履行计划信息
        performancePlanMapper.deleteByContractIds(ids);

        return contractInfoMapper.deleteContractInfoByIds(ids);
    }

    /**
     * 删除合同信息信息
     *
     * @param id 合同信息主键
     * @return 结果
     */
    @Override
    public int deleteContractInfoById(Long id)
    {
        return contractInfoMapper.deleteContractInfoById(id);
    }


    @AutoSetInsertValue
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertContractInfoWithFiles(ContractInfo contractInfo, MultipartFile[] files) {
        int insertCount = 0;
        insertCount = contractInfoMapper.insertContractInfo(contractInfo);
        if (null != files && files.length > 0) {
            for (MultipartFile file : files) {
                // 上传文件路径
                String filePath = RuoYiConfig.getUploadPath();
                // 上传并返回新文件名称
                String fileName = null;
                try {
                    fileName = FileUploadUtils.upload(filePath, file);
                    FileInfo fileInfo = new FileInfo();
                    fileInfo.setStatus(0);
                    fileInfo.setBusiId(contractInfo.getId());
                    fileInfo.setBusiType(BusinessTypeEnums.CONTRACT.getCode());
                    fileInfo.setFileName(file.getOriginalFilename());
                    fileInfo.setFileType(FileUploadUtils.getExtension(file));
                    fileInfo.setFileSize(file.getSize());
                    fileInfo.setFileUrl(fileName);
                    fileInfoMapper.insertFileInfo(fileInfo);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        // 履约计划信息
        String performancePlanJsonStr = contractInfo.getJsonStr();
        if (StringUtils.isNotEmpty(performancePlanJsonStr)) {
            ObjectMapper mapper = new ObjectMapper();
            try {
                CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, PerformancePlan.class);
                List<PerformancePlan> planList = mapper.readValue(performancePlanJsonStr,listType);
                if (CollectionUtils.isNotEmpty(planList)) {
                    for (PerformancePlan performancePlan : planList) {
                        performancePlan.setContractId(contractInfo.getId());
                        performancePlan.setUserId(contractInfo.getUserId());
                        performancePlan.setDeptId(contractInfo.getDeptId());
                        performancePlan.setStatus(0);
                        performancePlan.setActualPerformanceAmount(new BigDecimal(0));
                    }
                    performancePlanMapper.insertBatch(planList);
                }
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }


        return insertCount;
    }

    @AutoSetUpdateValue
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateContractInfoWithFiles(ContractInfo contractInfo, MultipartFile[] files) {
        int insertCount = 0;
        insertCount = contractInfoMapper.updateContractInfo(contractInfo);
        // 删除附件
        String deleteFileIdStr = contractInfo.getDeleteFileIdStr();
        if (StringUtils.isNotEmpty(deleteFileIdStr)) {
            // 逻辑删除附件信息
            fileInfoMapper.updateStatusByIdStr(deleteFileIdStr,1);
        }


        // 保存新增的文件
        if (null != files && files.length > 0) {
            for (MultipartFile file : files) {
                // 上传文件路径
                String filePath = RuoYiConfig.getUploadPath();
                // 上传并返回新文件名称
                String fileName = null;
                try {
                    fileName = FileUploadUtils.upload(filePath, file);
                    FileInfo fileInfo = new FileInfo();
                    fileInfo.setStatus(0);
                    fileInfo.setBusiId(contractInfo.getId());
                    fileInfo.setBusiType(BusinessTypeEnums.CONTRACT.getCode());
                    fileInfo.setFileName(file.getOriginalFilename());
                    fileInfo.setFileType(FileUploadUtils.getExtension(file));
                    fileInfo.setFileSize(file.getSize());
                    fileInfo.setFileUrl(fileName);
                    fileInfoMapper.insertFileInfo(fileInfo);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }



//        // 履约计划信息
//        String performancePlanJsonStr = contractInfo.getJsonStr();
//        if (StringUtils.isNotEmpty(performancePlanJsonStr)) {
//            ObjectMapper mapper = new ObjectMapper();
//            try {
//                CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, PerformancePlan.class);
//                List<PerformancePlan> planList = mapper.readValue(performancePlanJsonStr,listType);
//                for (PerformancePlan performancePlan : planList) {
//                    performancePlan.setContractId(contractInfo.getId());
//                    performancePlan.setUserId(contractInfo.getUserId());
//                    performancePlan.setDeptId(contractInfo.getDeptId());
//                    performancePlan.setStatus(0);
//                    performancePlan.setActualPerformanceAmount(new BigDecimal(0));
//                }
//                performancePlanMapper.insertBatch(planList);
//            } catch (JsonProcessingException e) {
//                throw new RuntimeException(e);
//            }
//        }


        return insertCount;
    }
}
